/////////////////////////////////////////
///file: jud_cmd_64
///Author: Dp
///////////////////////////////////////////////


module jud_cmd_64 (//input
	clk_1m,
	rst_n,
	oe_64,//等效成上层给的req
	frame_vaild,
	dll_data,
	sram_ack,
	p_err,
	sram_data_out,
	
	//output
	sram_wr,
	sram_rd,
	sram_addr,
	jud_err,
	end_flag
);

input clk_1m,rst_n,oe_64,frame_vaild;
input [7:0] dll_data;
input sram_ack;
input p_err;
input [7:0]sram_data_out;

output sram_wr,sram_rd;
output [12:0]sram_addr;
output end_flag;//结束标志位
output jud_err;

reg 	jud_err_reg;//判断芯片是否为好的标志位
reg [3:0] col_parity;//列校验寄存器
reg sram_wr_reg;
reg sram_rd_reg;
reg [12:0]sram_addr_reg;
reg [3:0] state;
reg [3:0] nstate;
reg [3:0]  sram_rd_data;
//reg flag;

wire	stONE,
		stDone,
		stTWO;

parameter uidg00_addr64 = 13'd0;
parameter uidg01_addr64 = 13'd1;
parameter IDLE  = 4'b0,   RD_ONE = 4'd1,  
		  ONE   = 4'd2,   RD_TWO = 4'd3,
		  TWO   = 4'd4,   THREE  = 4'd5, 
		  FOUR  = 4'd6,   FIVE   = 4'd7, SIX = 4'd8,    SEVEN = 4'd9,   
		  EIGHT = 4'd10,  NINE   = 4'd11, TEN = 4'd12,  ELEVEN = 4'd13, DONE = 4'd14;
		
	///********output assign**********/////////
assign  jud_err     = jud_err_reg;
assign  end_flag	=  (state == DONE) ? 1'b1:1'b0;	
assign	sram_addr	=	oe_64	?	sram_addr_reg	:   13'd0;
assign	sram_rd		=	oe_64	?	sram_rd_reg	    :	1'b0;
assign	sram_wr		=	oe_64	?	sram_wr_reg	    :	1'b0;
assign  stONE = state == ONE;
assign  stTWO = state == TWO;	
assign 	stDone = state == DONE;


///********state machine**********/////////
always @(posedge clk_1m or negedge rst_n)
    if(rst_n == 1'b0)
	   state <= IDLE;
	else if(oe_64 == 1'b0)
	   state <= IDLE;
	else
	   state <= nstate;

always @(*)
if(rst_n ==	1'b0)
	nstate	=	IDLE;
else if(oe_64	==	1'b0)
	     nstate = IDLE;
else	
	case(state)
		IDLE   : nstate = (~oe_64)?IDLE:RD_ONE;
		RD_ONE : nstate = (~oe_64)?IDLE:(sram_ack ? ONE : RD_ONE);
		ONE    : nstate = (~oe_64)?IDLE:(frame_vaild?RD_TWO:ONE);
		RD_TWO : nstate = (~oe_64)?RD_TWO:(sram_ack ? TWO : RD_TWO);
		TWO    : nstate = (~oe_64)?IDLE:(frame_vaild?THREE:TWO);
		THREE  : nstate = (~oe_64)?IDLE:(frame_vaild?FOUR:THREE);
		FOUR   : nstate = (~oe_64)?IDLE:(frame_vaild?FIVE:FOUR);	
		FIVE   : nstate = (~oe_64)?IDLE:(frame_vaild?SIX:FIVE);
		SIX    : nstate = (~oe_64)?IDLE:(frame_vaild?SEVEN:SIX);		
		SEVEN  : nstate = (~oe_64)?IDLE:(frame_vaild?EIGHT:SEVEN);
		EIGHT  : nstate = (~oe_64)?IDLE:(frame_vaild?NINE:EIGHT);
		NINE   : nstate = (~oe_64)?IDLE:(frame_vaild?TEN:NINE);
		TEN    : nstate = (~oe_64)?IDLE:(frame_vaild?ELEVEN:TEN);
		ELEVEN : nstate = (~oe_64)?IDLE:(frame_vaild?DONE:ELEVEN);
		DONE   : nstate = (~oe_64)?IDLE:(DONE);
		default: nstate = 2'bxx;
	endcase

	
always@(posedge	clk_1m or negedge rst_n)
	if(~rst_n)
		begin
			sram_addr_reg	<=	13'd0;
			sram_wr_reg		<=	1'b0;
			sram_rd_reg     <=  1'b0;
			col_parity      <=  4'd0;
			//flag 			<=  1'b0;
		end
	else if(~oe_64)
		begin
			sram_addr_reg	<=	13'd0;
			sram_wr_reg		<=	1'b0;	
			sram_rd_reg     <=  1'b0;
			col_parity      <=  4'd0;
		end
	else case(state)
	IDLE:
	begin	
			sram_addr_reg	<=	uidg00_addr64;
			sram_rd_reg  	<=  1'b1;
			col_parity      <=  4'd0;	
	end
	RD_ONE:
		begin
			if(sram_ack)
				begin
				sram_addr_reg <= uidg01_addr64;
				sram_rd_reg <= 1'b0;
				sram_rd_data <= sram_data_out[3:0];
				end
		end
	ONE:
	begin
		if(frame_vaild && (!p_err))
		 begin
			col_parity <= dll_data[3:0];
			sram_rd_reg <= 1'b1;
		 end
		
	end
	RD_TWO:
		begin
			if(sram_ack)
				begin
					sram_rd_data <= sram_data_out[3:0];
					sram_rd_reg  <= 1'b0;
				end
		end

	TWO:
	begin
		if(frame_vaild && (!p_err))
		 begin
			col_parity <= col_parity^dll_data[3:0];
		 end
	end
	THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN: 
		if(frame_vaild && (!p_err))
			begin
				col_parity <= col_parity ^ dll_data[3:0];
				sram_rd_reg <= 1'b0;
			end
	ELEVEN,DONE:
	begin
		sram_rd_reg <= 1'b0;
	end		
			
	default: 
			begin
			sram_addr_reg	<=	13'd0;
			sram_wr_reg		<=	1'b0;	
			sram_rd_reg     <=  1'b0;
			col_parity      <=  4'd0;
			end
	endcase
		 
	
always @(posedge clk_1m or negedge rst_n)
if(~rst_n)
	jud_err_reg <= 1'b0;
else if(~oe_64)
	jud_err_reg <= 1'b0;
else if(stDone)
	jud_err_reg <= jud_err_reg;
else if((state == ELEVEN) && frame_vaild)
	jud_err_reg <= (jud_err_reg ) || (dll_data[3:0] != col_parity);
else if((stONE | stTWO) && frame_vaild && (!p_err))
	jud_err_reg <= jud_err_reg || (dll_data[3:0] != sram_rd_data);
else if(frame_vaild)
	jud_err_reg <= jud_err_reg | p_err;


endmodule 













	
